package com.tarry.queue;

import lombok.extern.slf4j.Slf4j;

/**
 * 循环队列：减少常规队列中，对数据进行搬移的操作
 * <br>
 * <p>
 *     通过数组来实现队列，且当队列满时，队列中出队列指针和入队列指针存在以下关系
 *     （tail + 1） % capacity = head
 * </p>
 * @param <T>
 */
@Slf4j
public class CircularQueue<T> {

    //队列容量
    private int capacity;
    //队列出队指针
    private int head;
    //队列入队指针
    private int tail;
    private Object[] data;

    public CircularQueue(int capacity) {
        this.data = new Object[capacity];
        this.capacity = capacity;
        this.head = 0;
        this.tail = 0;
    }

    /**
     * 入队操作
     * <br>
     * <p>
     *     通过(this.tail + 1) % this.capacity == this.head算法，将存在环形队列中始终有一个空元素，
     *     即队列当真实容量为 this.capacity - 1f
     * </p>
     * @param item
     * @return
     */
    public boolean enQueue(T item) {
        if ( (this.tail + 1) % this.capacity == this.head ) {
            log.warn("the queue is full");
            return false;
        }
        this.data[this.tail] = item;
        this.tail = (this.tail + 1) % this.capacity;
        return true;
    }

    public T deQueue() {
        if ( this.tail == this.head) {
            log.warn("the queue is empty");
            return null;
        }
        T item = (T) this.data[this.head];
        this.head = (this.head + 1) % this.capacity;
        return item;
    }

    public void showQueue() {
        int tmp = this.head;
        while ( tmp % this.capacity != this.tail ){
            System.out.println("queue data is : " + this.data[tmp]);
            tmp ++ ;
        }
    }
}
